package cn.schoolwow.quickdao.module.database.ddl.action.kit;

import cn.schoolwow.quickdao.domain.database.ddl.IndexField;
import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickdao.domain.entity.Property;
import cn.schoolwow.quickdao.domain.entity.PropertyOption;
import cn.schoolwow.quickdao.domain.entity.common.TableColumn;
import cn.schoolwow.quickdao.domain.entity.create.CreateTableRequest;
import cn.schoolwow.quickdao.module.database.ddl.action.service.column.*;
import cn.schoolwow.quickdao.module.database.ddl.action.service.index.CreateIndexCompositeBusiness;
import cn.schoolwow.quickdao.module.database.ddl.action.service.index.DropIndexCompositeBusiness;
import cn.schoolwow.quickdao.module.database.ddl.action.service.table.*;
import cn.schoolwow.quickdao.module.database.ddl.query.kit.DatabaseDefinitionQuery;
import cn.schoolwow.quickdao.module.database.parent.kit.DatabaseDAOImpl;
import cn.schoolwow.quickflow.QuickFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DatabaseDefinitionActionImpl extends DatabaseDAOImpl implements DatabaseDefinitionAction {
    protected Logger logger = LoggerFactory.getLogger(DatabaseDefinitionActionImpl.class);

    private DatabaseDefinitionQuery databaseDefinitionQuery;

    public DatabaseDefinitionActionImpl(DatabaseDefinitionQuery databaseDefinitionQuery, QuickFlow quickFlow) {
        super(quickFlow);
        this.databaseDefinitionQuery = databaseDefinitionQuery;
    }

    @Override
    public void create(Class clazz) {
        Entity entity = quickDAOConfig.getEntityByClassName(clazz.getName());
        create(entity);
    }

    @Override
    public void create(Entity entity) {
        quickFlow.startFlow(new CreateTableFlow())
                .putTemporaryData("entity", entity)
                .execute();
    }

    @Override
    public void createTable(CreateTableRequest createTableRequest) {
        quickFlow.startFlow(new SetEntityByCreateTableRequestFlow())
                .next(new CreateTableFlow())
                .putTemporaryInstanceData(createTableRequest)
                .execute();
    }

    @Override
    public void renameTable(String oldTableName, String newTableName) {
        quickFlow.startFlow(new RenameTableCompositeBusiness())
                .putTemporaryData("oldTableName", oldTableName)
                .putTemporaryData("newTableName", newTableName)
                .putTemporaryData("tableName", oldTableName)
                .execute();
    }

    @Override
    public void dropTable(Class clazz) {
        Entity entity = quickDAOConfig.getEntityByClassName(clazz.getName());
        dropTable(entity.tableName);
    }

    @Override
    public void dropTable(String tableName) {
        quickFlow.startFlow(new DropTableCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .execute();
    }

    @Override
    public void rebuild(Class clazz) {
        if (databaseDefinitionQuery.hasTable(clazz)) {
            dropTable(clazz);
        }
        create(clazz);
    }

    @Override
    public void rebuild(String tableName) {
        if(databaseDefinitionQuery.hasTable(tableName)){
            dropTable(tableName);
        }
        Entity entity = quickDAOConfig.getDatabaseEntityByTableName(tableName);
        create(entity);
    }

    @Override
    public void createColumn(String tableName, PropertyOption propertyOption) {
        quickFlow.startFlow(new CreateColumnCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("propertyOption", propertyOption)
                .putTemporaryData("columnName", propertyOption.column)
                .execute();
    }

    @Override
    public void createColumn(String tableName, TableColumn tableColumn) {
        quickFlow.startFlow(new CreateColumnServiceFlow())
                .putTemporaryData("tableName", tableName)
                .putTemporaryInstanceData(tableColumn)
                .execute();
    }

    @Override
    public void renameTableColumn(String tableName, String oldTableColumn, String newTableColumn) {
        quickFlow.startFlow(new RenameTableColumnCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("oldTableColumn", oldTableColumn)
                .putTemporaryData("newTableColumn", newTableColumn)
                .execute();
    }

    @Override
    public void alterColumn(String tableName, PropertyOption propertyOption) {
        quickFlow.startFlow(new AlterColumnCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("propertyOption", propertyOption)
                .execute();
    }

    @Override
    public Property dropColumn(String tableName, String columnName) {
        FlowContext flowContext = quickFlow.startFlow(new DropColumnCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("columnName", columnName)
                .execute();
        Property property = flowContext.checkData("property", Property.class);
        return property;
    }

    @Override
    public void createIndex(IndexField indexField) {
        quickFlow.startFlow(new CreateIndexCompositeBusiness())
                .putTemporaryData("indexField", indexField)
                .putTemporaryData("tableName", indexField.tableName)
                .execute();
    }

    @Override
    public void dropIndex(String tableName, String indexName) {
        quickFlow.startFlow(new DropIndexCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("indexName", indexName)
                .execute();
    }

    @Override
    public void createForeignKey(String tableName, PropertyOption propertyOption) {
        quickFlow.startFlow(new CreateForeignKeyCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("propertyOption", propertyOption)
                .execute();
    }

    @Override
    public void enableForeignConstraintCheck(boolean enable) {
        quickFlow.startFlow(new EnableForeignConstraintCheckFlow())
                .putTemporaryData("enable", enable)
                .execute();
    }

    @Override
    public void backupTable(String tableName, String backupTableName) {
        quickFlow.startFlow(new BackupTableFlow())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("backupTableName", backupTableName)
                .execute();
    }

    @Override
    public void deleteDatabaseEntityCache(String... tableNames) {
        if(null==tableNames||tableNames.length==0){
            quickDAOConfig.databaseContext.databaseTableCache.clear();
        }else{
            for(String tableName:tableNames){
                quickDAOConfig.databaseContext.databaseTableCache.remove(tableName);
            }
        }
    }
}